/****************************************************************************
 * Copyright (c) 2008, 2009 Andreas Unger and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Andreas Unger - initial API and implementation 
 ****************************************************************************/

package org.eclipselabs.damos.library.logic.simulation;

import org.eclipselabs.damos.dml.DMLFactory;
import org.eclipselabs.damos.dml.DataType;
import org.eclipselabs.damos.dml.FloatingPointDataType;
import org.eclipselabs.damos.dml.FloatingPointFormat;
import org.eclipselabs.damos.dml.InputPort;
import org.eclipselabs.damos.dml.OutputPort;
import org.eclipselabs.damos.dml.util.DMLUtil;
import org.eclipselabs.damos.execution.executionmodel.DataFlowTargetEnd;
import org.eclipselabs.damos.library.logic.util.SchmittTriggerConstants;
import org.eclipselabs.damos.simulation.AbstractBlockSimulationObject;
import org.eclipselabs.damos.simulation.Value;
import org.eclipselabs.damos.simulation.ValueFactory;

/**
 * @author Andreas Unger
 *
 */
public class SchmittTriggerSimulationObject extends AbstractBlockSimulationObject {

	private Value trueValue;
	private Value falseValue;

	private Value upperThreshold;
	private Value lowerThreshold;

	private Value outputValue;
	
	public void initialize() {
		DataType t = getComponentDataType();

		trueValue = ValueFactory.INSTANCE.newValue(this, t, true);
		falseValue = ValueFactory.INSTANCE.newValue(this, t, false);
		
		DataType inputDataType;
		DataFlowTargetEnd targetEnd = getNode().getIncomingDataFlow(getBlock().getInputPorts().get(0));
		if (targetEnd != null) {
			inputDataType = targetEnd.getDataFlow().getSourceEnd().getNode().getDataType();
		} else {
			FloatingPointDataType floatingPointDataType = DMLFactory.eINSTANCE.createFloatingPointDataType();
			floatingPointDataType.setFormat(FloatingPointFormat.BINARY64);
			inputDataType = floatingPointDataType;
		}
		
		upperThreshold = ValueFactory.INSTANCE.newValue(this, inputDataType, DMLUtil.getArgumentValue(getBlock(), SchmittTriggerConstants.PARAMETER__UPPER_THRESHOLD, ""), 1);
		lowerThreshold = ValueFactory.INSTANCE.newValue(this, inputDataType, DMLUtil.getArgumentValue(getBlock(), SchmittTriggerConstants.PARAMETER__LOWER_THRESHOLD, ""), -1);
		outputValue = SchmittTriggerConstants.PARAMETER__INITIAL_OUTPUT__TRUE.equals(getBlock().getArgumentStringValue(SchmittTriggerConstants.PARAMETER__INITIAL_OUTPUT)) ? trueValue : falseValue;
	}
	
	public void consumeInputValue(InputPort inputPort, Value value) {
		if (value.compareTo(lowerThreshold) < 0) {
			outputValue = falseValue;
		} else if (value.compareTo(upperThreshold) > 0) {
			outputValue = trueValue;
		}
	}
	
	public Value getOutputValue(OutputPort outputPort) {
		return outputValue;
	}
	
}
